﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using VASJ.Model;
using System.Web.Security;

namespace VASJ.Service.Library.Manager
{
    public class OrganizationManager : BaseManager
    {
        /// <summary>
        /// Init
        /// </summary>
        /// <param name="_ApplicationName"></param>
        public OrganizationManager(string _ApplicationName)
            : base(_ApplicationName)
        {
        }

        #region "Private function"
        /// <summary>
        /// Author: Hoang Van Tai
        /// Get owner name of User or Organization for Id
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="IsStatus"></param>
        /// <returns></returns>
        public string GetOwner(Guid Id, bool IsStatus)
        {
            // Get Owner Name of Organization
            string sReturn = "";

            try
            {
                if (IsStatus)
                {
                    // User
                    sReturn = this.mdb.AHSAspnetUsers.Where(u => u.Userid == Id).Select(u => u.Username).FirstOrDefault();
                }
                else
                {
                    // Organization
                    sReturn = this.mdb.AHSOrganizations.Where(o => o.Id == Id).Select(o => o.Name).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOwner error {0}", ex);
            }

            return sReturn;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get Owner is user
        /// </summary>
        /// <param name="ownerid"></param>
        /// <returns></returns>
        public  bool GetOwnerisUser(string ownerid)
        {
            bool ret = true;

            var _org = this.mdb.AHSOrganizations.Where(o => o.Id == Guid.Parse(ownerid)).FirstOrDefault();

            // If Organization is Esxits 
            if (_org != null)
            {
                ret = false;
            }

            return ret;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the project type for ApplicationName
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <returns></returns>
        private int _GetProjectType()
        {
            // Get Project type Id 
            try
            {
                int ret = 0;
                var query = (int)(from p in this.mdb.AHSProjectTypes where (p.Name.ToLower() == this.ApplicationName.ToLower()) select p.Id).FirstOrDefault();

                if (query != 0)
                {
                    ret = query;
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager._GetProjectType {0}", ex);
                return 0;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the Organization into project for mainPrjId
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        private int _RemoveOrgsToProject(int mainPrjId, string[] idOrgRoles)
        {
            try
            {
                string idOrgs;

                if (idOrgRoles == null)
                {
                    var deletedAlls = from org in this.mdb.AHSOrganizationInProjects
                                      where (org.Projectid == mainPrjId) && 
                                            (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                      select org;

                    if (deletedAlls != null)
                    {
                        this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deletedAlls);
                    }
                }
                else
                {
                    idOrgs = "";

                    foreach (var idOrgRole in idOrgRoles)
                    {
                        // Format idOrg^idRole
                        string[] arrOrgRole = idOrgRole.Split('^');

                        idOrgs += arrOrgRole[0];
                        idOrgs += ",";
                    }

                    if (idOrgs.Trim() != "")
                    {
                        string idOrg = idOrgs.Substring(0, idOrgs.Length - 1);
                        var arrIdOrgDels = idOrg.Split(',').Select(x => Guid.Parse(x));

                        if (arrIdOrgDels.Any())
                        {
                            var deleteds = from org in this.mdb.AHSOrganizationInProjects
                                           where (org.Projectid == mainPrjId) && (arrIdOrgDels.Contains(org.Orgid) == false) &&
                                                 (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                           select org;

                            if (deleteds != null)
                            {
                                this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deleteds);
                            }
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager._RemoveOrgsToProject error {0}", ex);
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update the Organization and role of Organization  into project for mainPrjId
        /// </summary>
        /// <param name="mainPrjId"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        private int _UpdateOrgsToProject(int mainPrjId, string[] idOrgRoles)
        {
            try
            {
                foreach (var idOrgRole in idOrgRoles)
                {
                    // Format idUser^idRole
                    string[] arrOrgRole = idOrgRole.Split('^');

                    var orgs = (from org in this.mdb.AHSOrganizationInProjects
                                where (org.Orgid == Guid.Parse(arrOrgRole[0]) && (org.Projectid == mainPrjId)) && 
                                      (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) 
                                select org).FirstOrDefault();

                    if (orgs != null)
                    {
                        if ((arrOrgRole[1] == null) || (arrOrgRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            orgs.Roleid = null;
                        }
                        else
                        {
                            orgs.Roleid = Guid.Parse(arrOrgRole[1]);
                        }
                    }
                    else
                    {
                        // Add new item Org  in to Project
                        AHSDbContext.AHSOrganizationInProject orgInProject = new AHSDbContext.AHSOrganizationInProject();

                        orgInProject.Orgid = Guid.Parse(arrOrgRole[0]);
                        orgInProject.Projectid = mainPrjId;

                        if ((arrOrgRole[1] == null) || (arrOrgRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            orgInProject.Roleid = null;
                        }
                        else
                        {
                            orgInProject.Roleid = Guid.Parse(arrOrgRole[1]);
                        }

                        orgInProject.IsInvite = false;
                        orgInProject.Status = 1;

                        this.mdb.AHSOrganizationInProjects.InsertOnSubmit(orgInProject);
                    }
                }

                this.mdb.SubmitChanges();

                return 1;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager._UpdateOrgsToProject error {0}", ex);
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update the list Id user into the organization 
        /// </summary>
        /// <param name="OrgID"></param>
        /// <param name="idUsers"></param>
        /// <returns></returns>
        private int _UpdateUsersToOrganization(Guid OrgID, string[] idUsers)
        {
            try
            {
                ApplicationLinkManager alm = new ApplicationLinkManager(this.ApplicationName);
                string root = alm.GetLinkByApplication(); 

                foreach (var idUser in idUsers)
                {
                    Guid uidUser;

                    if (Guid.TryParse(idUser, out uidUser))
                    {
                        //Assign
                        var uios = (from uio in this.mdb.AHSUsersInOrganizations
                                    join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid
                                    where (uio.UserId == Guid.Parse(idUser) && (uio.OrgId == OrgID)) &&
                                          (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                    select uio).FirstOrDefault();

                        // Add new item User in to organization
                        if (uios == null)
                        {
                            AHSDbContext.AHSUsersInOrganization uio = new AHSDbContext.AHSUsersInOrganization();
                            uio.UserId = Guid.Parse(idUser);
                            uio.OrgId = OrgID;
                            uio.IsInvite = false;
                            uio.Status = 1;
                            this.mdb.AHSUsersInOrganizations.InsertOnSubmit(uio);
                        }
                    }
                    else
                    { 
                        //Invite
                        UserManager _UserManager= new UserManager(this.ApplicationName);
                        string email = idUser;
                        string message = string.Empty;

                        var ret = _UserManager.InsertInviteEmailOrg(email, OrgID, Guid.Parse("00000000-0000-0000-0000-000000000000"));
                        if  (!string.IsNullOrEmpty(root)) _UserManager.SendEmail(email, Guid.Parse(ret), ref message);
                    }
                }

                this.mdb.SubmitChanges();

                return 1;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager._UpdateUsersToOrganization error {0}", ex);
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the list Id User into the Organization
        /// </summary>
        /// <param name="OrgID"></param>
        /// <param name="idUsers"></param>
        /// <returns></returns>
        private int _RemoveUsersToOrganization(Guid OrgID, string[] idUsers)
        {
            try
            {
                string _idUsers;

                // If idUsers is null then remove all user into organization for OrgID
                if (idUsers == null || idUsers.Any() == false)
                {
                    var deletedAlls = from uio in this.mdb.AHSUsersInOrganizations
                                      join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid 
                                      where (uio.OrgId == OrgID) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                      select uio;

                    if (deletedAlls != null)
                    {
                        this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(deletedAlls);
                    }
                }
                else
                {
                    _idUsers = "";

                    foreach (var idUser in idUsers)
                    {
                        Guid uidUser;
                        if (Guid.TryParse(idUser, out uidUser))
                        {
                            _idUsers += idUser;
                            _idUsers += ",";
                        }
                    }

                    if (_idUsers.Trim() != "")
                    {
                        string idUser = _idUsers.Substring(0, _idUsers.Length - 1);
                        var arrIdUserDels = idUser.Split(',').Select(x => Guid.Parse(x));

                        if (arrIdUserDels.Any())
                        {
                            var deleteds = from uio in this.mdb.AHSUsersInOrganizations
                                           join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid 
                                           where (uio.OrgId == OrgID) && (arrIdUserDels.Contains(uio.UserId) == false) && 
                                                 (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                           select uio;

                            if (deleteds != null)
                            {
                                this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(deleteds);
                            }
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager._RemoveUsersToOrganization error {0}", ex);
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update the Organization into the list Id project for OrgID
        /// </summary>
        /// <param name="OrgID"></param>
        /// <param name="idPrjRoles"></param>
        /// <returns></returns>
        private int _UpdateOrgsToProject(Guid OrgID, string[] idPrjRoles)
        {
            //Update Org in to project by OrgID
            try
            {
                foreach (var idPrjRole in idPrjRoles)
                {
                    // Format idPrj^idRole
                    string[] arrPrjRole = idPrjRole.Split('^');

                    var orgs = (from org in this.mdb.AHSOrganizationInProjects
                                where (org.Projectid == Int32.Parse(arrPrjRole[0]) && (org.Orgid == OrgID)) && 
                                      (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                select org).FirstOrDefault();

                    if (orgs != null)
                    {
                        if ((arrPrjRole[1] == null) || (arrPrjRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            orgs.Roleid = null;
                        }
                        else
                        {
                            orgs.Roleid = Guid.Parse(arrPrjRole[1]);
                        }
                    }
                    else
                    {
                        // Add new item Org  in to Project
                        AHSDbContext.AHSOrganizationInProject orgInProject = new AHSDbContext.AHSOrganizationInProject();

                        orgInProject.Orgid = OrgID;
                        orgInProject.Projectid = Int32.Parse(arrPrjRole[0]);

                        if ((arrPrjRole[1] == null) || (arrPrjRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                        {
                            orgInProject.Roleid = null;
                        }
                        else
                        {
                            orgInProject.Roleid = Guid.Parse(arrPrjRole[1]);
                        }

                        orgInProject.Status = 1;
                        orgInProject.IsInvite = false;

                        this.mdb.AHSOrganizationInProjects.InsertOnSubmit(orgInProject);
                    }
                }

                this.mdb.SubmitChanges();

                return 1;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager._UpdateOrgsToProject error {0}", ex);
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the Organization into project for  AHSMainProject != this.ApplicationName + Default
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="OrgID"></param>
        /// <param name="idPrjRoles"></param>
        /// <returns></returns>
        private int _RemoveOrgsToProject(Guid OrgID, string[] idPrjRoles)
        {
            try
            {
                string idPrjs;

                if ((idPrjRoles == null) || (idPrjRoles.Any() == false))
                {
                    var deletedAlls = from org in this.mdb.AHSOrganizationInProjects
                                      where (org.Orgid == OrgID) && 
                                            (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                      select org;

                    if (deletedAlls != null)
                    {
                        this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deletedAlls);
                    }
                }
                else
                {
                    idPrjs = "";

                    foreach (var idPrjRole in idPrjRoles)
                    {
                        // Format idPrj^idRole
                        string[] arrPrjRole = idPrjRole.Split('^');

                        idPrjs += arrPrjRole[0];
                        idPrjs += ",";
                    }

                    if (idPrjs.Trim() != "")
                    {
                        string idPrj = idPrjs.Substring(0, idPrjs.Length - 1);
                        var arrIdPrjDels = idPrj.Split(',').Select(x => x);

                        if (arrIdPrjDels.Any())
                        {
                            var deleteds = from org in this.mdb.AHSOrganizationInProjects
                                           where (org.Orgid == OrgID) && (arrIdPrjDels.Contains(org.Projectid.ToString()) == false) &&
                                                 (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                           select org;

                            if (deleteds != null)
                            {
                                this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deleteds);
                            }
                        }
                    }
                }

                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager._RemoveOrgsToProject error {0}", ex);
                return -1;
            }
        }
        #endregion

        /// <summary>
        /// Get organization id list is exists inside application
        /// </summary>
        /// <returns></returns>
        public List<Guid> GetListOrganizationIDInApplication()
        {
            try
            {
                // Get organization list inside project
                List<Guid> list_oip = new List<Guid>();

                var oips = (from oip in this.mdb.AHSOrganizationInProjects
                           where oip.AHSMainProject.AHSProjectType.ApplicationName == this.ApplicationName && oip.Status.HasValue && oip.Status.Value == 1
                           select oip.Orgid).Distinct();

                foreach (var oip in oips)
                {
                    list_oip.Add(oip);
                }

                return list_oip;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetListOrganizationIDInApplication {0}", ex);
                return null;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// Get the organizationid list which contain user for application or user is own
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="userID"></param>
        /// <returns></returns>
        public string GetOrganizationIdForUser(Guid userID)
        {
            // Get List Organization Id for userID
            string ret = "";

            try
            {
                var organizations = (from uio in this.mdb.AHSUsersInOrganizations
                                     join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid
                                     where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uio.UserId == userID || (oip.AHSOrganization.OwnerIsUser.HasValue && oip.AHSOrganization.OwnerIsUser.Value && oip.AHSOrganization.OwnerID.HasValue && oip.AHSOrganization.OwnerID.Value == userID))
                                     select new { orgId = uio.AHSOrganization.Id, Name = uio.AHSOrganization.Name }).Distinct();

                string idOrgs;

                //Get list organization Id
                var sb = new System.Text.StringBuilder();

                foreach (var item in organizations)
                {
                    sb.Append(item.orgId.ToString());
                    sb.Append(',');
                }

                idOrgs = sb.ToString();

                if (idOrgs.Trim() != "")
                {
                    ret = idOrgs.Substring(0, idOrgs.Length - 1);
                }

                sb = null;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOrganizationIdForUser error {0}", ex);
            }

            return ret;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the list oranization for application and not  application + default
        /// </summary>
        /// <returns></returns>
        public Dictionary<Guid, Organization> GetOrganization()
        {
            Dictionary<Guid, AHSModel.Organization> lst = new Dictionary<Guid, Organization>();

            try
            {
                //Get Organization on Project
                var orgs = (from org in this.mdb.AHSOrganizationInProjects
                           where (org.Status.HasValue && org.Status.Value == 1) && (org.AHSMainProject.ProjectTypeID.HasValue) && 
                                 (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) 
                           select org.AHSOrganization).Distinct();

                foreach (var org in orgs)
                {
                    if (!lst.ContainsKey(org.Id))
                    {
                        AHSModel.Organization it = new Organization();
                        it.Id = org.Id;
                        it.Name = org.Name;
                        it.Description = org.Description;
                        it.OrgType = org.OrgType;
                        it.OwnerID = org.OwnerID;
                        it.OwnerIsUser = org.OwnerIsUser;
                        it.ProjectType = org.ProjectType;
                        it.Roleid = org.RoleID;
                        lst.Add(it.Id, it);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOrganization error {0}", ex);
            }

            return lst;
        }

        /// <summary>
        /// Author: Phong
        /// Add organization 
        /// </summary>
        /// <returns></returns>
        /// Modify: Hoang Van Tai, move Helper to OrganizationManager
        public bool AddOrganization(string name, string description, string[] idUsers, string[] idPrjRoles, Guid OwnerID)
        {
            bool retVal = true;

            try
            {
                //Add organization
                AHSDbContext.AHSOrganization org = new AHSDbContext.AHSOrganization();

                org.Id = Guid.NewGuid();
                org.Name = name;
                org.Description = description;
                org.OwnerID = OwnerID;
                org.OwnerIsUser = true;

                this.mdb.AHSOrganizations.InsertOnSubmit(org);

                //Add the related user
                if (idUsers != null)
                {
                    for (int i = 0; i < idUsers.Length; i++)
                    {
                        Guid _idUser;

                        if (Guid.TryParse(idUsers[i], out _idUser) && _idUser != Guid.Empty)
                        {
                            AHSDbContext.AHSUsersInOrganization uio = new AHSDbContext.AHSUsersInOrganization();

                            uio.UserId = _idUser;
                            uio.OrgId = org.Id;
                            uio.IsInvite = false;
                            uio.Status = 1;

                            this.mdb.AHSUsersInOrganizations.InsertOnSubmit(uio);
                        }
                    }
                }

                //Add the related project
                if (idPrjRoles != null)
                {
                    for (int i = 0; i < idPrjRoles.Length; i++)
                    {
                        string[] PrjRole = idPrjRoles[i].Split('^');

                        if (PrjRole.Length == 2)
                        {
                            //validate format idPrj(int)^idRole(Guid)
                            int PrjID = 0;
                            Guid RoleID = Guid.Empty;

                            if (Int32.TryParse(PrjRole[0], out PrjID) && PrjID != 0 && Guid.TryParse(PrjRole[1], out RoleID) && RoleID != Guid.Empty)
                            {
                                //validate value idPrj and idRole
                                AHSDbContext.AHSOrganizationInProject oip = new AHSDbContext.AHSOrganizationInProject();

                                oip.Projectid = PrjID;
                                oip.Roleid = RoleID;
                                oip.Orgid = org.Id;
                                oip.IsInvite = false;
                                oip.Status = 1;

                                this.mdb.AHSOrganizationInProjects.InsertOnSubmit(oip);
                            }
                        }
                    }
                }

                //Add to first project
                var findPrj = (from prj in this.mdb.AHSMainProjects
                              where prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                              select prj.Id).Take(1);

                if (findPrj != null && findPrj.Any())
                {
                    AHSDbContext.AHSOrganizationInProject oip = new AHSDbContext.AHSOrganizationInProject();

                    oip.Projectid = findPrj.FirstOrDefault();
                    oip.Roleid = null;
                    oip.Orgid = org.Id;
                    oip.IsInvite = false;
                    oip.Status = 1;

                    this.mdb.AHSOrganizationInProjects.InsertOnSubmit(oip);
                }

                this.mdb.SubmitChanges();
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                retVal = false;
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.AddOrganization error {0}", ex);
            }
            return retVal;
        }
        
        /// <summary>
        /// Author: Hoang Van Tai
        /// Add organization  
        /// </summary>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="organtype"></param>
        /// <param name="orgrole"></param>
        /// <param name="ownerid"></param>
        /// <param name="ownertype"></param>
        /// <param name="userInvite"></param>
        /// <param name="projecttype"></param>
        /// <param name="userNames"></param>
        /// <param name="idPrjRoles"></param>
        /// <param name="userRoles"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public Guid? AddOrganization(string name, string description, string organtype, string orgrole, string ownerid, string ownertype, string userInvite, string projecttype, string[] userNames, string[] idPrjRoles, string[] userRoles, ref string msgError)
        {
            try
            {
                if (string.IsNullOrEmpty(name))
                {
                    return null;
                }

                var org = new AHSDbContext.AHSOrganization();
                bool ownerisUser = true;

                org.Id = Guid.NewGuid();
                org.Name = name.Trim();
                org.Description = (description != null) ? description.Trim() : string.Empty;

                //(ownerid == null not set )
                if (ownerid != null)
                {
                    ownerisUser = GetOwnerisUser(ownerid);
                    org.OwnerID = Guid.Parse(ownerid);
                    org.OwnerIsUser = ownerisUser;
                }
                else
                {
                    org.OwnerID = null;
                    org.OwnerIsUser = true;
                }
                org.OrgType = Convert.ToInt32(organtype);

                //Role
                if (!string.IsNullOrEmpty(orgrole))
                {
                    if (orgrole == "00000000-0000-0000-0000-000000000000")
                    {
                        org.RoleID = null;
                    }
                    else
                    {
                        org.RoleID = Guid.Parse(orgrole);
                    }
                }
                else
                {
                    org.RoleID = null;
                }

                // Project Type
                if (! string.IsNullOrEmpty(projecttype))
                {
                    org.ProjectType = Int32.Parse(projecttype);
                }
                else
                {
                    org.ProjectType = null;
                }

                org.Active = true;
                org.Description = string.IsNullOrEmpty(description) ? null : description.Trim();
                this.mdb.AHSOrganizations.InsertOnSubmit(org);
                this.mdb.SubmitChanges();

                // if not add project
                if (idPrjRoles == null)
                {
                    //Add to first project
                    var findPrj = (from prj in this.mdb.AHSMainProjects
                                   where prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
                                   orderby prj.Id
                                   select prj.Id).Take(1);

                    if (findPrj != null && findPrj.Any())
                    {
                        AHSDbContext.AHSOrganizationInProject oip = new AHSDbContext.AHSOrganizationInProject();

                        oip.Projectid = findPrj.FirstOrDefault();
                        oip.Roleid = null;
                        oip.Orgid = org.Id;
                        oip.IsInvite = false;
                        oip.Status = 1;

                        this.mdb.AHSOrganizationInProjects.InsertOnSubmit(oip);
                    }

                    this.mdb.SubmitChanges();
                }

                //UserInOrganizationManager manager = new UserInOrganizationManager();
                //UserManager manager = new UserManager(this.ApplicationName);

                //Add UserInOrg: Assign, Invite 
                if (userNames != null)
                {
                    AddUsersToOrg(org.Id, userInvite, userNames, ref msgError);
                }

                //Add UserInOrg: Role
                if (userRoles != null)
                {
                    SaveUsersRoleToOrg(org.Id, userInvite, userRoles, ref msgError);
                }

                //Add Project and role to Org 
                if (idPrjRoles != null)
                {
                    SaveOrgsRoleToPrj(org.Id, userInvite, idPrjRoles, ref msgError);
                }

                return org.Id;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.AddOrganization error {0}", ex);
                msgError = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Author: Phong
        /// Get the organization for user
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        /// Modify: Hoang Van Tai. move Helper to OrganizationManager, edit  ApplicationName.ToLower()
        public Dictionary<Guid, Organization> GetOrganizationForUser(Guid userID)
        {
            Dictionary<Guid, Organization> lst = new Dictionary<Guid, Organization>();

            try
            {
                var organizations = (from uio in this.mdb.AHSUsersInOrganizations
                                    join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid
                                    where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (uio.UserId == userID || (oip.AHSOrganization.OwnerIsUser.HasValue && oip.AHSOrganization.OwnerIsUser.Value && oip.AHSOrganization.OwnerID.HasValue && oip.AHSOrganization.OwnerID.Value == userID))
                                    select uio.AHSOrganization).Distinct();

                foreach (var item in organizations)
                {
                    if (!lst.ContainsKey(item.Id))
                    {
                        Organization entity = new Organization();

                        entity.Id = item.Id;
                        entity.Name = item.Name;
                        if (!string.IsNullOrEmpty(item.Description)) entity.Description = item.Description; ;
                        entity.OwnerID = item.OwnerID;
                        entity.OwnerIsUser = item.OwnerIsUser;

                        // If Owner is Organization
                        if (entity.OwnerIsUser != null)
                        {
                            if (item.OwnerID != null)
                            {
                                if (!(entity.OwnerIsUser.Value))
                                {
                                    entity.OwnerName = GetOwner(item.OwnerID.Value, false);
                                }
                                else
                                {
                                    entity.OwnerName = GetOwner(item.OwnerID.Value, true);
                                }
                            }
                        }

                        entity.OrgType = item.OrgType;
                        entity.Roleid = item.RoleID;
                        entity.ProjectType = item.ProjectType;

                        lst.Add(item.Id, entity);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] GetOrganizationForUser error {0}", ex);
                return null;
            }

            return lst;
        }

        /// <summary>
        /// Author: Phong
        /// Get the organization for project
        /// </summary>
        /// <param name="projectID"></param>
        /// <returns></returns>
        /// Modify: Hoang Van Tai, edit: (org.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
        public Dictionary<Guid, Organization> GetOrganizationForProject(int projectID)
        {
            Dictionary<Guid, Organization> lst = new Dictionary<Guid, Organization>();

            try
            {
                var organizations = (from org in this.mdb.AHSOrganizations
                                    join oip in this.mdb.AHSOrganizationInProjects on org.Id equals oip.Orgid
                                    where (oip.Projectid == projectID) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                     select new { Id = org.Id, Name = org.Name, Description = org.Description, OwnerID = org.OwnerID, OwnerIsUser = org.OwnerIsUser, TypeOrg = org.OrgType, RoleOrg = oip.Roleid, Rolename = oip.AHSAspnetRole.Rolename, ProjectType = org.ProjectType }).Distinct();

                foreach (var item in organizations)
                {
                    if (!lst.ContainsKey(item.Id))
                    {
                        Organization entity = new Organization();

                        entity.Id = item.Id;
                        entity.Name = item.Name;

                        if (!string.IsNullOrEmpty(item.Description)) entity.Description = item.Description;

                        entity.OwnerID = item.OwnerID;
                        entity.OwnerIsUser = item.OwnerIsUser;

                        // If Owner is Organization
                        if (entity.OwnerIsUser != null)
                        {
                            if (item.OwnerID != null)
                            {
                                if (!(entity.OwnerIsUser.Value))
                                {
                                    entity.OwnerName = GetOwner(item.OwnerID.Value, false);
                                }
                                else
                                {
                                    entity.OwnerName = GetOwner(item.OwnerID.Value, true);
                                }
                            }
                        }

                        entity.TypeOrg = item.TypeOrg;
                        entity.Roleid = item.RoleOrg;
                        entity.RoleName = item.Rolename;

                        entity.ProjectType = item.ProjectType;

                        lst.Add(item.Id, entity);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOrganizationForProject error {0}", ex);
                return null;
            }
            return lst;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get the organization for projectId, projectType
        /// </summary>
        /// <param name="projectID"></param>
        /// <returns></returns>
        public List<Organization> GetOrganizationForProject(int projectID, string rolename)
        {
            List<Organization> lst = new List<Organization>();

            try
            {
                var organizations = (from org in this.mdb.AHSOrganizations
                                    join oip in this.mdb.AHSOrganizationInProjects on org.Id equals oip.Orgid
                                    where (oip.Projectid == projectID) && (oip.AHSAspnetRole.Rolename == rolename) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                    select new { Id = org.Id, Name = org.Name, Description = org.Description, OwnerID = org.OwnerID, OwnerIsUser = org.OwnerIsUser, TypeOrg = org.OrgType, RoleOrg = oip.Roleid, ProjectType = org.ProjectType }).Distinct();

                foreach (var item in organizations)
                {
                    Organization entity = new Organization();

                    entity.Id = item.Id;
                    entity.Name = item.Name;

                    if (!string.IsNullOrEmpty(item.Description)) entity.Description = item.Description;

                    entity.OwnerID = item.OwnerID;
                    entity.OwnerIsUser = item.OwnerIsUser;

                    // If Owner is Organization
                    if (entity.OwnerIsUser != null)
                    {
                        if (item.OwnerID != null)
                        {
                            if (!(entity.OwnerIsUser.Value))
                            {
                                entity.OwnerName = GetOwner(item.OwnerID.Value, false);
                            }
                            else
                            {
                                entity.OwnerName = GetOwner(item.OwnerID.Value, true);
                            }
                        }
                    }

                    entity.TypeOrg = item.TypeOrg;
                    entity.Roleid = item.RoleOrg;
                    entity.ProjectType = item.ProjectType;

                    lst.Add(entity);
                }
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOrganizationForProject error {0}", ex);

                return null;
            }
            return lst;
        }

        /// <summary>
        /// Author: Le Anh Phong
        /// </summary>
        /// <returns></returns>
        public List<OrgInProject> GetProjectInvitedOrganization(Guid orgID, ref string msgError)
        {
            try
            {
                var pios = (from pio in this.mdb.AHSOrganizationInProjects
                           where (pio.Orgid == orgID) && (pio.IsInvite == true) && 
                                (pio.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select pio).Distinct();

                List<OrgInProject> lst = new List<OrgInProject>();
                foreach (var pio in pios)
                {
                    var oip = new OrgInProject();

                    oip.Id = pio.Id;
                    oip.OrgId = pio.Orgid;
                    oip.ProjectId = pio.Projectid;
                    oip.IsInvite = pio.IsInvite;
                    oip.Status = pio.Status;
                    oip.UserInvite = pio.UserInvite;
                    oip.RoleId = pio.Roleid;
                    if (pio.Roleid.HasValue) oip.RoleName = pio.AHSAspnetRole.Rolename;

                    oip.OrgName = pio.AHSOrganization.Name;
                    oip.ProjectName = pio.AHSMainProject.Name;

                    lst.Add(oip);
                }

                return lst;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetProjectInvitedOrganization error {0}", ex);
                msgError = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Author: Le Anh Phong
        /// Change status Org in Project
        /// </summary>
        /// <param name="orgID"></param>
        /// <param name="prjID"></param>
        public int ChangeStatusOrganInProject(Guid orgID, int prjID, int status, ref string msgError)
        {
            try
            {
                var pios = from pio in this.mdb.AHSOrganizationInProjects
                           where (pio.Orgid == orgID) && (pio.Projectid == prjID) && 
                                (pio.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select pio;
                var pi = pios.FirstOrDefault();

                if (pi != null)
                {
                    pi.Status = status;

                    this.mdb.SubmitChanges();
                }
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.ChangeStatusOrganInProject error {0}", ex);
                msgError = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// </summary>
        /// <param name="OrgId"></param>
        /// <returns></returns>
        public List<Organization> SearchOrganizationSA(string OrgId, ref string msgError)
        {
            try
            {

                List<Organization> result = new List<Organization>();
                IEnumerable<AHSDbContext.AHSOrganization> Organizations = null;
                

                if ((OrgId != null))
                {
                    Organizations = (from org in this.mdb.AHSOrganizations
                                    join oip in this.mdb.AHSOrganizationInProjects on org.Id equals(oip.Orgid)  
                                    where (org.Id == Guid.Parse(OrgId)) && 
                                        (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                    select org).Distinct();

                }
                else
                {
                    Organizations = (from org in this.mdb.AHSOrganizations
                                    join oip in this.mdb.AHSOrganizationInProjects on org.Id equals (oip.Orgid)
                                    where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                    select org).Distinct();
                }

                if (Organizations == null)
                {
                    return null;
                }

                foreach (var item in Organizations)
                {
                    var org = new Organization();

                    org.Id = item.Id;
                    org.Name = item.Name;
                    org.Description = item.Description;
                    org.OwnerID = item.OwnerID;
                    org.OwnerIsUser = item.OwnerIsUser;
                    org.TypeOrg = item.OrgType;
                    org.OrgType = item.OrgType;
                    org.Roleid = item.RoleID;

                    org.RoleOrgID = item.RoleID;
                    if (item.RoleID.HasValue)
                    {
                        org.RoleName = item.AHSAspnetRole.Rolename;
                    }
                    org.ProjectType = item.ProjectType;

                    result.Add(org);
                }

                return result;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.SearchOrganizationSA error {0}", ex);
                msgError = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Update the organization 
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="OrgID"></param>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="idUsers"></param>
        /// <param name="idPrjRoles"></param>
        /// <returns></returns>
        public bool UpdateOrganization(Guid OrgID, string name, string description, string[] idUsers, string[] idPrjRoles)
        {
            bool ret = false;

            try
            {
                AHSDbContext.AHSOrganization org = (from o in this.mdb.AHSOrganizations
                                                    where o.Id == OrgID
                                                    select o).FirstOrDefault();

                if (org != null)
                {
                    org.Name = name;
                    org.Description = (description != null) ? description.Trim() : string.Empty;
                    org.OrgType = 0;
                    org.OwnerIsUser = true;

                    this.mdb.SubmitChanges();

                    // Remove Users to Organization
                    _RemoveUsersToOrganization(OrgID, idUsers);

                    // Update User in Organization
                    if (idUsers != null)
                    {
                        _UpdateUsersToOrganization(OrgID, idUsers);
                    }

                    // Remove Organization to Projects 
                    _RemoveOrgsToProject(OrgID, idPrjRoles);

                    // Update Organization in Projects
                    if (idPrjRoles != null)
                    {
                        _UpdateOrgsToProject(OrgID, idPrjRoles);
                    }
                }

                ret = true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.UpdateOrganization error {0}", ex);
            }

            return ret;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="OrgID"></param>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="idUsers"></param>
        /// <returns></returns>
        public bool UpdateOrganization(Guid OrgID, string name, string description, string[] idUsers)
        {
            bool ret = false;

            try
            {
                AHSDbContext.AHSOrganization org = (from o in this.mdb.AHSOrganizations
                                                    where o.Id == OrgID
                                                    select o).FirstOrDefault();

                if (org != null)
                {
                    org.Name = name;
                    org.Description = (description != null) ? description.Trim() : string.Empty;
                    org.OrgType = 0;
                    org.OwnerIsUser = true;

                    this.mdb.SubmitChanges();

                    // Remove Users to Organization
                    _RemoveUsersToOrganization(OrgID, idUsers);

                    // Update User in Organization
                    if (idUsers != null)
                    {
                        _UpdateUsersToOrganization(OrgID, idUsers);
                    }

                }

                ret = true;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.UpdateOrganization error {0}", ex);
            }

            return ret;
        }
        /// <summary>
        /// Author: Hoang Van Tai
        /// Update Organization
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="name"></param>
        /// <param name="description"></param>
        /// <param name="organtype"></param>
        /// <param name="orgrole"></param>
        /// <param name="ownerid"></param>
        /// <param name="ownertype"></param>
        /// <param name="userInvite"></param>
        /// <param name="projecttype"></param>
        /// <param name="idUsers"></param>
        /// <param name="idPrjRoles"></param>
        /// <returns></returns>
        public int UpdateOrganization(string orgId, string name, string description, string organtype, string orgrole, string ownerid, string ownertype, string userInvite, string projecttype, string[] idUsers, string[] idPrjRoles, ref string msgError)
        {
            try
            {
                Guid OrgID = Guid.Parse(orgId);
                AHSDbContext.AHSOrganization org = (from o in this.mdb.AHSOrganizations
                                                    join oip in this.mdb.AHSOrganizationInProjects on o.Id equals (oip.Orgid)
                                                    where (o.Id == OrgID) && 
                                                          (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                                    select o).FirstOrDefault();

                bool ownerisUser = true;

                if (org != null)
                {
                    org.Name = name;
                    org.Description = (description != null) ? description.Trim() : string.Empty;
                    org.OrgType = 0;

                    if (ownerid != null)
                    {
                        ownerisUser = GetOwnerisUser(ownerid);
                        org.OwnerID = Guid.Parse(ownerid);
                        org.OwnerIsUser = ownerisUser;
                    }
                    else
                    {
                        org.OwnerID = null;
                        org.OwnerIsUser = true;
                    }

                    //Role
                    if (!string.IsNullOrEmpty(orgrole))
                    {
                        if (orgrole == "00000000-0000-0000-0000-000000000000")
                        {
                            org.RoleID = null;
                        }
                        else
                        {
                            org.RoleID = Guid.Parse(orgrole);
                        }
                    }
                    else
                    {
                        org.RoleID = null;
                    }

                    // Project Type
                    if (!string.IsNullOrEmpty(projecttype))
                    {
                        org.ProjectType = Int32.Parse(projecttype);
                    }
                    else
                    {
                        org.ProjectType = null;
                    }


                    this.mdb.SubmitChanges();

                    // Remove Users to Organization
                    _RemoveUsersToOrganization( OrgID, idUsers);

                    // Update User in Organization
                    if (idUsers != null)
                    {
                        _UpdateUsersToOrganization(OrgID, idUsers);
                    }

                    // Remove Organization to Projects 
                    _RemoveOrgsToProject(OrgID, idPrjRoles);

                    // Update Organization in Projects
                    if (idPrjRoles != null)
                    {
                        _UpdateOrgsToProject(OrgID, idPrjRoles);
                    }
                }

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();

                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.UpdateOrganization error {0}", ex);
                msgError = ex.Message;
                
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Assign user join org
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="userInvite"></param>
        /// <param name="message"></param>
        /// <param name="userNames"></param>
        /// <returns></returns>
        public int AssignUsersToOrg(Guid orgId, string username, string[] userNames, ref string msgError)
        {
            try
            {

                ApplicationLinkManager alm = new ApplicationLinkManager(this.ApplicationName);
                string root = alm.GetLinkByApplication(); 

                var userInviteID = (from u in this.mdb.AHSAspnetUsers
                                    where (u.Username.ToLower() == username.ToLower())
                                    select u.Userid).FirstOrDefault();

                foreach (var userId in userNames)
                {

                    UserManager _UserManager;


                    string email;
                    bool _IsInvite = false;
                    bool _Flag = false;
                    Guid uId;
                    //string _userId = userId.Substring(0, userId.Length - 3);
                    string _userId = userId;

                    int index = userId.LastIndexOf("[");
                    if (index != -1)
                    {
                        _userId = userId.Substring(0, index);
                    }

                    if (Guid.TryParse(_userId, out uId))
                    {

                        var query = (from u in this.mdb.AHSAspnetUsers
                                     where u.Userid == Guid.Parse(_userId)
                                     select u).FirstOrDefault();

                        _Flag = (query != null);

                        _userId = userId.Substring(userId.Length - 2, 1);

                        //_IsInvite = _userId == "1" ? true : false;
                        _IsInvite = _userId == "-2" ? true : false;

                    }
                    else
                    {
                        _IsInvite = true;
                    }

                    // User is not exist in System
                    if ((!_Flag) && (_IsInvite))
                    {

                        _UserManager = new UserManager(this.ApplicationName);
                        email = userId.Substring(0, userId.Length - 4);

                        var ret = _UserManager.InsertInviteEmailOrg(email, orgId, Guid.Parse("00000000-0000-0000-0000-000000000000"));
                        if (ret != null) _UserManager.SendEmail(email, Guid.Parse(ret), ref msgError);
                    }
                    else
                    {
                        // Assign Or Invite 

                        var csuserinorg = new AHSDbContext.AHSUsersInOrganization();
                        csuserinorg.OrgId = orgId;
                        csuserinorg.UserId = uId;
                        csuserinorg.IsInvite = _IsInvite; //Invite = true; Assign = false 

                        //Guid.TryParse(userInviteID, out uId);
                        csuserinorg.UserInvite = userInviteID;

                        // Assign
                        if (!_IsInvite)
                        {
                            csuserinorg.Status = 1;


                        }
                        else
                        {
                            csuserinorg.Status = -1;
                        }

                        this.mdb.AHSUsersInOrganizations.InsertOnSubmit(csuserinorg);


                        //Add Known: Hiện tại bên CS chưa có kiểu này
                        //OrganizationManager om = new OrganizationManager(this.ApplicationName);
                        //om.AddKnown(csuserinorg.UserId, csuserinorg.OrgId);
                        //if (csuserinorg.UserInvite != null) om.AddKnown(csuserinorg.UserInvite.Value, csuserinorg.OrgId);

                        // Add user into Application
                        this.AddUserToApplication(uId.ToString());

                    }

                }

                this.mdb.SubmitChanges();
                
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.AssignUsersToOrg error {0}", ex);
                msgError = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="userInvite"></param>
        /// <param name="message"></param>
        /// <param name="userNames"></param>
        /// <returns></returns>
        public int AddUsersToOrg(Guid orgId, string userInvite, string[] userNames, ref string msgError)
        {
            try
            {
                var userInviteID = (from u in this.mdb.AHSAspnetUsers
                                    where (u.Username.ToLower() == userInvite.ToLower())
                                    select u.Userid).FirstOrDefault();

                ApplicationLinkManager alm = new ApplicationLinkManager(this.ApplicationName);
                string root = alm.GetLinkByApplication(); 

                foreach (var userId in userNames)
                {
                    UserManager _UserManager;

                    
                    string email;
                    bool _IsInvite = false;
                    bool _Flag = false;
                    Guid uId;

                    if (Guid.TryParse(userId, out uId))
                    {
                        var query = (from u in this.mdb.AHSAspnetUsers
                                     where u.Userid == Guid.Parse(userId)
                                     select u).FirstOrDefault();

                        _Flag = (query != null);

                        _IsInvite = false;

                    }
                    else
                    {
                        _IsInvite = true;
                    }

                    // User is not exist in System
                    if ((!_Flag) && (_IsInvite))
                    {
                        _UserManager = new UserManager(this.ApplicationName);
                        email = userId;

                        var ret = _UserManager.InsertInviteEmailOrg(email, orgId, Guid.Parse("00000000-0000-0000-0000-000000000000"));
                        if (string.IsNullOrEmpty(ret)) _UserManager.SendEmail(email, Guid.Parse(ret), ref msgError);
                    }
                    else
                    {
                        // Assign Or Invite 
                        var csuserinorg = new AHSDbContext.AHSUsersInOrganization(); 
                        csuserinorg.OrgId = orgId;
                        csuserinorg.UserId = uId;
                        csuserinorg.IsInvite = _IsInvite; //Invite = true; Assign = false 

                        //Guid.TryParse(userInviteID, out uId);
                        csuserinorg.UserInvite = userInviteID;

                        // Assign
                        if (!_IsInvite)
                        {
                            csuserinorg.Status = 1;
                        }
                        else
                        {
                            csuserinorg.Status = -1;
                        }

                        this.mdb.AHSUsersInOrganizations.InsertOnSubmit(csuserinorg);

                        //Add Known: Hiện tại trong CS không có
                        //om.AddKnown(csuserinorg.UserId, csuserinorg.OrgId);
                        //if (csuserinorg.UserInvite != null) om.AddKnown(csuserinorg.UserInvite.Value, csuserinorg.OrgId);

                        // Add user into Application
                        this.AddUserToApplication(uId.ToString());

                    }
                }

                this.mdb.SubmitChanges();


                
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.cs.AddUsersToOrg error {0}", ex);
                msgError = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="userInvite"></param>
        /// <param name="userRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int SaveUsersRoleToOrg(Guid orgId, string userInvite, string[] userRoles, ref string msgError)
        {
            try
            {
                var userInviteID = (from u in this.mdb.AHSAspnetUsers
                                    where (u.Username.ToLower() == userInvite.ToLower())
                                    select u.Userid).FirstOrDefault();

                foreach (var item in userRoles)
                {
                    string[] arrUserRole = item.Split('^');
                    var userId = Guid.Parse(arrUserRole[0]);
                    var userInOrg = (from uio in this.mdb.AHSUsersInOrganizations
                                     join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId  equals (oip.Orgid)
                                     where (uio.OrgId == orgId) && (uio.UserId == userId) && 
                                        (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                     select uio).FirstOrDefault();

                    Guid? _roleId = null;

                    if  ((arrUserRole[1] == "null") || (arrUserRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                    {
                        _roleId = null;
                    }
                    else
                    {
                        _roleId = Guid.Parse(arrUserRole[1]);
                    }

                    // Update
                    if (userInOrg != null)
                    {
                        userInOrg.RoleId = _roleId;
                        userInOrg.UserInvite = userInviteID;
                    }
                    else
                    { // New
                        userInOrg = new AHSDbContext.AHSUsersInOrganization(); 
                        userInOrg.UserId = userId;
                        userInOrg.OrgId = orgId;
                        userInOrg.RoleId = _roleId;
                        userInOrg.Status = 1;
                        userInOrg.IsInvite = false;
                        userInOrg.UserInvite = userInviteID;

                        this.mdb.AHSUsersInOrganizations.InsertOnSubmit(userInOrg);
                    }
                }

                this.mdb.SubmitChanges();
                
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.SaveUsersRoleToOrg error {0}", ex);
                msgError = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Comment: Save Org and Role to Project
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="userInvite"></param>
        /// <param name="prjRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int SaveOrgsRoleToPrj(Guid orgId, string userInvite, string[] prjRoles, ref string msgError)
        {
            try
            {
                var userInviteID = (from u in this.mdb.AHSAspnetUsers
                                    where (u.Username.ToLower() == userInvite.ToLower())
                                    select u.Userid).FirstOrDefault();

                foreach (var item in prjRoles)
                {
                    string[] arrPrjRole = item.Split('^');
                    var prjId = int.Parse(arrPrjRole[0]);
                    var orgInPrj = (from oip in this.mdb.AHSOrganizationInProjects
                                    where (oip.Orgid == orgId) && (oip.Projectid == prjId) 
                                    select oip).FirstOrDefault();

                    Guid? _roleId = null;
                    if ((arrPrjRole[1]  == "null") || (arrPrjRole[1].ToString() == "00000000-0000-0000-0000-000000000000"))
                    {
                        _roleId = null;
                    }
                    else
                    {
                        _roleId = Guid.Parse(arrPrjRole[1]);
                    }

                    // Update
                    if (orgInPrj != null)
                    {
                        orgInPrj.Roleid = _roleId;
                        orgInPrj.UserInvite = userInviteID;
                    }
                    else
                    { // New
                        orgInPrj = new AHSDbContext.AHSOrganizationInProject();
                        orgInPrj.Orgid = orgId;
                        orgInPrj.Projectid = prjId;
                        orgInPrj.Roleid = _roleId;
                        orgInPrj.Status = 1;
                        orgInPrj.IsInvite = false;
                        orgInPrj.UserInvite = userInviteID;

                        this.mdb.AHSOrganizationInProjects.InsertOnSubmit(orgInPrj);
                    }
                }

                this.mdb.SubmitChanges();
                
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.cs.SaveOrgsRoleToPrj error {0}", ex);
                msgError = ex.Message;

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get List Org from User
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<Organization> GetOrgsListFromUser(string userId, ref string msgError)
        {
            try
            {
                List<Organization> ret = new List<Organization>();
                if (userId == null)
                    return ret;
                Guid uId;
                if (!Guid.TryParse(userId, out uId))
                    return null;

                var list = (from org in this.mdb.AHSOrganizations
                           join uip in this.mdb.AHSOrganizationInProjects on org.Id equals (uip.Orgid)
                           join uio in this.mdb.AHSUsersInOrganizations on org.Id equals(uio.OrgId)
                           where (uio.UserId == uId) && 
                           (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           orderby org.Name
                           select new { org = org, status = uio.Status, roleId = uio.RoleId}).Distinct();

                foreach (var item in list)
                {
                    var org = new AHSModel.Organization();

                    org.Id = item.org.Id;
                    org.Name = item.org.Name;
                    org.Description = item.org.Description;
                    org.OwnerID = item.org.OwnerID;
                    org.OwnerIsUser = item.org.OwnerIsUser;
                    org.TypeOrg = item.org.OrgType;
                    org.OrgType = item.org.OrgType;
                    org.Status = item.status;
                    org.Roleid = item.roleId;

                    org.RoleOrgID = item.org.RoleID;
                    if (item.org.RoleID.HasValue)
                    {
                        org.RoleName = item.org.AHSAspnetRole.Rolename;
                    }
                    org.ProjectType = org.ProjectType;

                    ret.Add(org);
                }
                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOrgsListFromUser error {0}", ex);
                msgError = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get List Org by SA
        /// </summary>
        /// <param name="user"></param>
        /// <param name="orgName"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public List<Organization> GetOrganizationsListNotOrgName(string orgName, ref string msgError)
        {
            try
            {
                List<Organization> ret = new List<Organization>();

                var orgs = (from org in this.mdb.AHSOrganizations
                            join oip in this.mdb.AHSOrganizationInProjects on org.Id equals (oip.Orgid)
                            where (org.Name.ToLower() != orgName.ToLower()) &&
                                     (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                            orderby org.Name
                            select org).Distinct();

                foreach (var item in orgs)
                {
                    var org = new Organization();

                    org.Id = item.Id;
                    org.Name = item.Name;
                    org.Description = item.Description;
                    org.OwnerID = item.OwnerID;
                    org.OwnerIsUser = item.OwnerIsUser;
                    org.TypeOrg = item.OrgType;
                    org.OrgType = item.OrgType;
                    org.Roleid = item.RoleID;

                    org.RoleOrgID = item.RoleID;
                    if (item.RoleID.HasValue)
                    {
                        org.RoleName = item.AHSAspnetRole.Rolename;
                    }
                    org.ProjectType = item.ProjectType;

                    ret.Add(org);
                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOrganizationsList error {0}", ex);
                msgError = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get List Org where user by SA
        /// </summary>
        /// <param name="user"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public List<Organization> GetOrganizationsListBySA(ref string msgError)
        {
            // Get Organization list where Normal and Empowering  
            try
            {
                List<Organization> ret = new List<Organization>();

                var query = (from org in this.mdb.AHSOrganizations
                            join oip in this.mdb.AHSOrganizationInProjects on org.Id equals (oip.Orgid) 
                            join u in this.mdb.AHSAspnetUsers on org.OwnerID equals u.Userid into Org_U
                            from r in Org_U.DefaultIfEmpty()
                            where (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) 
                            orderby org.Name
                            select new { Id = org.Id, Name = org.Name, Description = org.Description, Owner = r.Username, OwnerID = org.OwnerID, OwnerIsUser = org.OwnerIsUser, TypeOrg = org.OrgType, RoleOrg = org.RoleID, ProjectType = org.ProjectType }).Distinct();


                //0: Normal , 1: Empowering
                //var orgs = orgTable.Select(a => a).OrderBy(a => a.Name);
                Organization obj;

                foreach (var item in query)
                {
                    obj = new Organization();
                    obj.Id = item.Id;
                    obj.Name = item.Name;
                    obj.Description = item.Description;
                    //obj.Roleid = item.RoleOrg;

                    obj.OwnerID = item.OwnerID;
                    obj.OwnerIsUser = item.OwnerIsUser == null ? false : true;

                    // If Owner is Organization
                    if  (obj.OwnerIsUser != null)
                    {
                        if (!(obj.OwnerIsUser.Value) && (item.OwnerID != null))
                        {
                            obj.OwnerName = GetOwner(item.OwnerID.Value, obj.OwnerIsUser.Value);
                        }
                        else
                        {
                            obj.OwnerName = item.Owner;
                        }
                    }

                    obj.TypeOrg = item.TypeOrg;
                    obj.Roleid = item.RoleOrg;
                    obj.ProjectType = item.ProjectType;

                    ret.Add(obj);
                    obj = null;
                }
                
                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOrganizationsListBySA error {0}", ex);
                msgError = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove User in Org is delete 
        /// </summary>
        /// <param name="idUserDels"></param>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public int RemoveUsersFromOrg(string[] idUserDels, Guid orgId, ref string msgError)
        { 
            try
            {
                foreach (var item in idUserDels)
                {
                    var deleteds = from uio in this.mdb.AHSUsersInOrganizations
                                   join oip in this.mdb.AHSOrganizationInProjects on uio.OrgId equals oip.Orgid
                                   where (uio.OrgId == orgId) && (uio.UserId == Guid.Parse(item)) &&
                                         (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   select uio;

                    this.mdb.AHSUsersInOrganizations.DeleteAllOnSubmit(deleteds);

                    //Delete InviteEmail
                    var query = from ivt in this.mdb.AHSInviteEmails where (ivt.OrgID == orgId) && (ivt.Code == Guid.Parse(item)) select ivt;
                    this.mdb.AHSInviteEmails.DeleteAllOnSubmit(query);

                }

                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.RemoveUsersFromOrg error {0}", ex);
                msgError = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add Organization which User known
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="OrgID"></param>
        public void AddKnown(Guid UserID, Guid OrgKnownID, bool submit = true)
        {
            try
            {
                var knownExist = from k in this.mdb.AHSUserKnownOrgans
                                 where (k.UserID == UserID) && (k.OrganKnownID == OrgKnownID) 
                                 select k;
                if (knownExist.FirstOrDefault() == null)
                {
                    //Not exist
                    AHSDbContext.AHSUserKnownOrgan obj = new AHSDbContext.AHSUserKnownOrgan(); 
                    obj.UserID = UserID;
                    obj.OrganKnownID = OrgKnownID;
                    this.mdb.AHSUserKnownOrgans.InsertOnSubmit(obj);
                    if (submit) this.mdb.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.AddKnown error {0}", ex);
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Delete the Oraganization for ApplicationName and OrgID
        /// </summary>
        /// <param name="OrgID"></param>
        /// <returns></returns>
        public bool DeleteOrganization(Guid OrgID)
        {
            bool retVal = true;

            try
            {
                var orgs = from org in this.mdb.AHSOrganizationInProjects
                           where (org.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (org.Orgid == OrgID)
                           select org;

                this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(orgs);

                this.mdb.SubmitChanges();
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                retVal = false;
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.DeleteOrganization error {0}", ex);
            }

            return retVal;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove the organization into the project for ApplicationName
        /// </summary>
        /// <param name="ProjectID"></param>
        /// <returns></returns>
        public bool RemoveOrgsFromProject(int ProjectID)
        {
            bool retVal = true;

            try
            {
                var oips = from oip in this.mdb.AHSOrganizationInProjects
                           where (oip.Projectid == ProjectID) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                           select oip;

                this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(oips);

                this.mdb.SubmitChanges();
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                retVal = false;
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.RemoveOrgsFromProject error {0}", ex);
            }

            return retVal;
        }

        /// <summary>
        /// Author: Phong
        /// Add the organization into project for ApplicationName
        /// </summary>
        /// <param name="ApplicationName"></param>
        /// <param name="ProjectID"></param>
        /// <param name="idOrgs"></param>
        /// <returns></returns>
        /// Modify: Hoang Van Tai, Move Helper to OrganizationManager , prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()
        public bool AddOrgsToProject(int ProjectID, string[] idOrgs)
        {
            bool retVal = true;

            try
            {
                //Check validate project
                var prjs = (from prj in this.mdb.AHSMainProjects
                            where (prj.ProjectTypeID.HasValue) && (prj.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) && (prj.Id == ProjectID)
                            select prj).FirstOrDefault();

                if (prjs != null)
                {
                    //Validate project
                    for (int i = 0; i < idOrgs.Length; i++)
                    {
                        string[] idOIP = idOrgs[i].Split('^');
                        Guid OrgID = Guid.Empty;
                        Guid RoleID = Guid.Empty;

                        if (Guid.TryParse(idOIP[0], out OrgID) && OrgID != Guid.Empty && Guid.TryParse(idOIP[1], out RoleID) && RoleID != Guid.Empty)
                        {
                            AHSDbContext.AHSOrganizationInProject oip = new AHSDbContext.AHSOrganizationInProject();
                            oip.Projectid = ProjectID;
                            oip.Orgid = OrgID;
                            oip.Roleid = RoleID;
                            oip.IsInvite = false;
                            oip.Status = 1;
                            this.mdb.AHSOrganizationInProjects.InsertOnSubmit(oip);
                        }
                    }

                    this.mdb.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
                retVal = false;
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.AddOrgsToProject error {0}", ex);
            }

            return retVal;
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove Organization in Project is delete 
        /// </summary>
        /// <param name="idPrjDels"></param>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public int RemoveProjectsFromOrg(string[] idPrjDels, Guid orgId)
        { 
            try
            {
                foreach (var item in idPrjDels)
                {
                    var deleteds = from oip in this.mdb.AHSOrganizationInProjects 
                                   where (oip.Orgid == orgId) && (oip.Projectid == int.Parse(item))  &&
                                         (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   select oip;
                    this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deleteds);
                }
                this.mdb.SubmitChanges();

                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.RemoveProjectsFromOrg error {0}", ex);
                return -1;
            }
        }

        /// <summary>
        /// Author:Hoang Van Tai
        /// Comment:Save list Id Project into the Organization
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="userInvite"></param>
        /// <param name="idPrjDels"></param>
        /// <param name="PrjRoles"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public int SavePrjsRoleToOrg(string orgId, string userInvite, string[] idPrjDels, string[] PrjRoles, ref string message)
        {
            if (string.IsNullOrEmpty(orgId))
            {
                message = "Organization id is empty";
                return -1;
            }
            try
            {
                //Remove Organization in Project
                if (idPrjDels != null)
                {
                    RemoveProjectsFromOrg(idPrjDels, Guid.Parse(orgId));
                }

                // Project is role: Update 
                if (PrjRoles != null)
                {
                    SaveOrgsRoleToPrj(Guid.Parse(orgId), userInvite, PrjRoles, ref message);
                }

                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.SavePrjsRoleToOrg error {0}", ex);
                message = ex.Message;
                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get Project List From Organization
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public List<OrgInProject> GetProjectListFromOrganization(string orgId, ref string msgError)
        {
            try
            {
                List<OrgInProject> ret = new List<OrgInProject>();
                Guid uId;
                if (!Guid.TryParse(orgId, out uId)) return null;

                var list = (from mp in this.mdb.AHSMainProjects
                           join oip in this.mdb.AHSOrganizationInProjects  on mp.Id equals oip.Projectid
                           join org in this.mdb.AHSOrganizations on oip.Orgid equals org.Id
                           orderby mp.Name
                           where (oip.Orgid == uId) && (mp.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) 
                           select new { OrgId = oip.Orgid, OrgName = org.Name, ProjectId = oip.Projectid, ProjectName = mp.Name, ProjectType = mp.AHSProjectType.Id, IsPM = mp.AHSProjectType.IsPM, RoleId = oip.Roleid, status = oip.Status }).Distinct();

                foreach (var item in list)
                {
                    ret.Add(new OrgInProject(item.OrgId, item.OrgName, item.ProjectId, item.ProjectName, item.ProjectType, item.IsPM.Value, item.RoleId, item.status.Value));
                }

                return ret;
            }
            catch (System.Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetProjectListFromOrganization error {0}", ex);
                msgError = ex.Message;

                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Remove Org in Prj is delete 
        /// </summary>
        /// <param name="idOrgDels"></param>
        /// <param name="idPrj"></param>
        /// <returns></returns>
        public int RemoveOrgsFromProject(string[] idOrgDels, int idPrj)
        { 
            try
            {
                foreach (var item in idOrgDels)
                {
                    string[] orgid = item.Split('^');

                    var deleteds = from oip in this.mdb.AHSOrganizationInProjects
                                   where (oip.Projectid == idPrj) && (oip.Orgid == Guid.Parse(orgid[0])) && 
                                         (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower()) 
                                   select oip;
                    
                    this.mdb.AHSOrganizationInProjects.DeleteAllOnSubmit(deleteds);
                }

                this.mdb.SubmitChanges();
                return 0;
            }
            catch (Exception ex)
            {
                this.mdb.RejectChanges();
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.RemoveOrgsFromProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add Org to Project
        /// </summary>
        /// <param name="idPrj"></param>
        /// <param name="message"></param>
        /// <param name="idOrgRoles"></param>
        /// <returns></returns>
        public int AddOrgsToProject(int idPrj, string[] idOrgRoles, ref string message)
        {
            try
            {

                foreach (var idOrgRole in idOrgRoles)
                {
                    string[] arrOrgRole = idOrgRole.Split('^');
                    var orgId = Guid.Parse(arrOrgRole[0]);
                    Guid? _roleId = null;


                    if (arrOrgRole[1].ToString() == "00000000-0000-0000-0000-000000000000")
                    {
                        _roleId = null;
                    }
                    else
                    {
                        _roleId = Guid.Parse(arrOrgRole[1]);
                    }

                    var orgInPrj = new AHSDbContext.AHSOrganizationInProject();
                    orgInPrj.Projectid = idPrj;
                    orgInPrj.Orgid = orgId;
                    orgInPrj.Roleid = _roleId;
                    orgInPrj.Status = 1;
                    orgInPrj.IsInvite = false;

                    this.mdb.AHSOrganizationInProjects.InsertOnSubmit(orgInPrj);
                }
                this.mdb.SubmitChanges();
                
                return 0;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.AddOrgsToProject error {0}", ex);

                return -1;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get list  Organization and User is Owner
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public List<Organization> GetOwnersList(string user)
        {
            try
            {
                List<Organization> ret = new List<Organization>();
                Organization _obj;

                // SA
                if (Vianova.AHSService.Utils.MembershipHelper.CheckAdmin(user))
                {
                    // Organization
                    var orgs = (from org in this.mdb.AHSOrganizations
                               join oip in this.mdb.AHSOrganizationInProjects on org.Id equals oip.Orgid
                               orderby (org.Name)
                               where (org.OrgType == 0) && 
                                     (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                               select (new { Id = org.Id, Name = org.Name })).Distinct();

                    foreach (var item in orgs)
                    {
                        _obj = new Organization();
                        _obj.Id = item.Id;
                        _obj.Name = item.Name;
                        _obj.OwnerIsUser = false;
                        ret.Add(_obj);
                        _obj = null;
                    }

                    // User
                    var query = (from u in this.mdb.AHSAspnetUsers
                                 join uip in this.mdb.AHSUserInProjects on u.Userid equals uip.Userid
                                 orderby (u.Username)
                                 where (u.AHSAspnetMembership.Isapproved == 1) && (u.AHSAspnetMembership.Islockedout == 0) &&
                                       (uip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                 select (new { Id = u.Userid, Name = u.Username })).
                                Union(from u in this.mdb.AHSAspnetUsers
                                      orderby (u.Username)
                                      where (u.AHSAspnetMembership.Isapproved == 1) && (u.AHSAspnetMembership.Islockedout == 0) &&
                                      (u.Username.ToLower() == "sa")
                                      select (new { Id = u.Userid, Name = u.Username })).Distinct();

                    foreach (var item in query)
                    {
                        _obj = new Organization();
                        _obj.Id = item.Id;
                        _obj.Name = item.Name;
                        _obj.OwnerIsUser = true;
                        ret.Add(_obj);
                        _obj = null;
                    }
                }
                else
                {
                    // Any User
                    var UserId = (from u in this.mdb.AHSAspnetUsers
                                  where (u.Username.ToLower() == user.ToLower()) 
                                  select u.Userid).FirstOrDefault();

                    // Organization Owner
                    if (UserId != null)
                    {
                        var list = (from org in this.mdb.AHSOrganizations
                                   join oip in this.mdb.AHSOrganizationInProjects on org.Id equals oip.Orgid
                                   where (org.OwnerID == UserId) && 
                                        (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                   orderby (org.Name)
                                   select (new { Id = org.Id, Name = org.Name })).Distinct();

                        foreach (var item in list)
                        {
                            _obj = new Organization();
                            _obj.Id = item.Id;
                            _obj.Name = item.Name;
                            _obj.OwnerIsUser = false;
                            ret.Add(_obj);
                            _obj = null;
                        }

                        var listOrg = (from org in this.mdb.AHSOrganizations
                                      join oip in this.mdb.AHSOrganizationInProjects on org.Id equals oip.Orgid
                                      join uio in this.mdb.AHSUsersInOrganizations on org.OwnerID equals uio.OrgId
                                      where (uio.UserId == UserId) && (uio.Status == 1) &&
                                            (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                                      select (new { Id = org.Id, Name = org.Name })).Distinct();

                        foreach (var item in listOrg)
                        {
                            _obj = new Organization();
                            _obj.Id = item.Id;
                            _obj.Name = item.Name;
                            _obj.OwnerIsUser = false;
                            ret.Add(_obj);
                            _obj = null;
                        }

                        // User
                        var query = from u in this.mdb.AHSAspnetUsers
                                    where u.Userid == UserId
                                    orderby (u.Username)
                                    select (new { Id = u.Userid, Name = u.Username });

                        foreach (var item in query)
                        {
                            _obj = new Organization();
                            _obj.Id = item.Id;
                            _obj.Name = item.Name;
                            _obj.OwnerIsUser = true;
                            ret.Add(_obj);
                            _obj = null;
                        }
                    }
                }
                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetOwnersList error {0}", ex);
                return null;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Add the exist user into application
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool AddUserToApplication(string userId)
        {
            try
            {
                Guid _userId;

                if (Guid.TryParse(userId, out _userId))
                {
                    UserManager um = new UserManager(this.ApplicationName);

                    if (!um.IsExistUser(_userId))
                    {
                        um.AddUserToApplication(userId);
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] UserManager.AddUserToApplication error {0}", ex);

                return false;
            }
        }

        /// <summary>
        /// Author: Hoang Van Tai
        /// Get Organization by primaryKey
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="msgError"></param>
        /// <returns></returns>
        public Organization GetById(string orgId, ref string msgError)
        {
            try
            {
                Organization ret = null ;

                var query = (from org in this.mdb.AHSOrganizations
                             join oip in this.mdb.AHSOrganizationInProjects on org.Id equals oip.Orgid
                             join u in this.mdb.AHSAspnetUsers on org.OwnerID equals u.Userid into Org_U
                             from r in Org_U.DefaultIfEmpty()
                             where (org.Id == Guid.Parse(orgId)) && (oip.AHSMainProject.AHSProjectType.ApplicationName.ToLower() == this.ApplicationName.ToLower())
                             select new { Id = org.Id, Name = org.Name, Description = org.Description, Owner = r.Username, OwnerID = org.OwnerID, OwnerIsUser = org.OwnerIsUser, TypeOrg = org.OrgType, RoleOrg = org.RoleID, ProjectType = org.ProjectType }).FirstOrDefault();

                if (query != null)
                {
                    ret = new Organization();
                    ret.Id = query.Id;
                    ret.Name = query.Name;
                    ret.Description = query.Description;


                    ret.OwnerID = query.OwnerID;
                    ret.OwnerIsUser = query.OwnerIsUser == null ? false : true;

                    // If Owner is Organization
                    if (ret.OwnerIsUser != null)
                    {
                        if (!(ret.OwnerIsUser.Value) && (query.OwnerID != null))
                        {
                            ret.OwnerName = GetOwner(query.OwnerID.Value, ret.OwnerIsUser.Value);
                        }
                        else
                        {
                            ret.OwnerName = query.Owner;
                        }
                    }

                    ret.TypeOrg = query.TypeOrg;
                    ret.Roleid = query.RoleOrg;
                    ret.ProjectType = query.ProjectType;

                }

                return ret;
            }
            catch (Exception ex)
            {
                Logger.Log.ErrorFormat("[" + this.ApplicationName + "] OrganizationManager.GetByPrimaryKey error {0}", ex);
                msgError = ex.Message;

                return null;
            }


        }

    }
}